package com.hyts.mvc.initialize;

import com.google.common.collect.Lists;
import com.hyts.mvc.annotation.MvcBootApplication;
import com.hyts.mvc.base.WebOrder;
import com.hyts.mvc.bean.MvcConfigBean;
import com.hyts.mvc.boot.war.MvcWarTargetPointer;
import com.hyts.mvc.config.MvcValue;
import com.hyts.mvc.configure.WebMvcConfigurer;
import com.hyts.mvc.configure.WebMvcConfigurerAdapter;
import com.hyts.mvc.configure.WebMvcConfigurerRegistry;
import com.hyts.mvc.context.WebMvcContext;
import com.hyts.mvc.context.WebServletContextAware;
import com.hyts.mvc.loader.WebMvcConfigLoader;
import com.hyts.mvc.loader.item.WebMvcAnnotationConfigLoader;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.stream.Collectors;

/**
 * project-name:coffice-toolbox
 * package-name:com.hyts.mvc.boot
 * author:Libo/Alex
 * create-date:2019-07-01 15:34
 * email:liboware@gmail.com
 * description:此类主要用于:
 * 总体mvc容器初始化启动服务-注册相关系统和新的servlet组件，作为所有的服务的入口工作
 * @author Administrator
 */
@Slf4j
@HandlesTypes({WebMvcConfigurerAdapter.class,MvcWarTargetPointer.class})
public class WebMvcServletContainerInitializer implements ServletContainerInitializer{


    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) {
        // 驱动class类是否为空!
        if(Objects.isNull(WebMvcContext.getBootstrapMainClass())){
            return ;
        }
        //进行全局绑定servletContext对象-servletContext对象
        WebServletContextAware.setServletContext(ctx);
        //进行操作控制服务-webMvcConfigure注册中心服务对象
        WebMvcConfigurerRegistry webMvcConfigurerRegistry = new WebMvcConfigurerRegistry();
        c.parallelStream().map(param->{
            //判断是否实现了order接口
            if(WebOrder.class.isAssignableFrom(param) && !param.isInterface() &&
                    !Modifier.isAbstract(param.getModifiers())){
                try {
                    return (WebOrder)param.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                   log.error("初始化失败",e);
                }
            }
            return null;
        }).filter(Objects::nonNull).sorted(Comparator.comparingInt(WebOrder::value)).forEach(param->{
//                if(MvcWarTargetPointer.class.isAssignableFrom(param.getClass())){
//                    MvcValue.DEFAULT_PACKAGE_NAME.delete(0, MvcValue.DEFAULT_PACKAGE_NAME.length());
//                    MvcValue.DEFAULT_PACKAGE_NAME.append(param.getClass().getPackage().getName());
//                }
                if(WebMvcConfigurer.class.isAssignableFrom(param.getClass()) && !param.getClass().isInterface() &&
                    !Modifier.isAbstract(param.getClass().getModifiers())){
                    WebMvcConfigurerAdapter webMvcConfigurer = (WebMvcConfigurerAdapter)param;
                    //执行所有相关的组件注册功能
                    webMvcConfigurer.build(webMvcConfigurerRegistry);
                    webMvcConfigurer.addWebServlet();
                    webMvcConfigurer.addWebFilter();
                    webMvcConfigurer.addWebListener();
                }
            //判断系统是否采取package指定模式-指定模式的话进行控制
        });
        //进行控制服务
        ServiceLoader<WebMvcConfigLoader> loaders = ServiceLoader.load(WebMvcConfigLoader.class);
        List<WebMvcConfigLoader> sortedLoaders = Lists.newLinkedList(loaders);
        MvcConfigBean configBean = new MvcConfigBean();
        List<WebMvcConfigLoader> dataList = sortedLoaders.parallelStream().sorted(Comparator.comparingInt(WebMvcConfigLoader::order)).
                collect(Collectors.toList());
            for(WebMvcConfigLoader param3:dataList){
                //如果为注解操作服务
                MvcBootApplication mvcBootApplication = null;
                if (WebMvcAnnotationConfigLoader.class.getName().equals(param3.getClass().getName())){
                    mvcBootApplication = param3.getClass().getAnnotation(MvcBootApplication.class);
                    if(mvcBootApplication != null){
                        log.info("读取系统定位服务类（扩展）MvcBootApplication注解服务加载系统配置");
                        configBean = (MvcConfigBean) param3.load(mvcBootApplication,configBean);
                    }else{
                        mvcBootApplication = (MvcBootApplication) WebMvcContext.getBootstrapMainClass().
                                getAnnotation(MvcBootApplication.class);
                        configBean = (MvcConfigBean) param3.load(mvcBootApplication,configBean);
                        log.info("读取MvcBootApplication注解服务加载系统配置");
                        mvcBootApplication = (MvcBootApplication) WebMvcContext.getBootstrapMainClass().getAnnotation(MvcBootApplication.class);
                        configBean = (MvcConfigBean) param3.load(mvcBootApplication,configBean);
                    }
                }else{
                    try {
                        log.info("读取application.properties配置文件加载系统配置");
                        configBean = (MvcConfigBean) param3.load(null,configBean);
                    } catch (Exception e) {
                        log.warn("未完成读取配置文件进行初始化信息配置!");
                    }
                }

        }
        WebMvcContext.setMvcProperties(configBean);
    }
}
